import csv
import matplotlib.pyplot as plt
import numpy as np
import codecs

# 设置matplotlib支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用黑体显示中文
plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号

def generate_comparison_chart(csv_file_path):
    try:
        # 尝试不同的编码方式读取文件
        encodings = ['utf-8', 'gbk', 'gb2312', 'ansi']
        data = []
        
        for encoding in encodings:
            try:
                print(f"尝试使用 {encoding} 编码读取文件...")
                with open(csv_file_path, 'r', encoding=encoding) as f:
                    reader = csv.DictReader(f)
                    data = list(reader)
                print(f"成功使用 {encoding} 编码读取文件")
                break
            except UnicodeDecodeError:
                continue
        
        if not data:
            print("所有编码尝试都失败了，请检查文件格式")
            return
        
        # 转换数值类型
        for row in data:
            try:
                row['count8'] = int(row['count8'])
                row['count10'] = int(row['count10'])
            except ValueError:
                row['count8'] = 0
                row['count10'] = 0
        
        print(f"CSV文件读取成功，共读取到 {len(data)} 行数据")
        
        # 过滤state为"成功"的数据，并按rulename分组统计
        rule_counts = {}
        for row in data:
            # 过滤state为"成功"的记录
            if row.get('state') == '失败':
                rulename = row['rulename']
                if rulename not in rule_counts:
                    rule_counts[rulename] = {'count8': 0, 'count10': 0}
                rule_counts[rulename]['count8'] += row['count8']
                rule_counts[rulename]['count10'] += row['count10']
        
        # 过滤掉count8为0的规则，避免计算百分比时除以0
        # valid_rule_counts = {}
        # for rule, counts in rule_counts.items():
        #     if counts['count8'] > 0:
        #         valid_rule_counts[rule] = counts
        # rule_counts = valid_rule_counts
        
        # # 如果没有符合条件的数据，提前返回
        # if not rule_counts:
        #     print("没有找到state为'成功'且count8>0的数据")
        #     return
        
        # 准备绘图数据
        rules = list(rule_counts.keys())
        # 计算count10相对于count8的百分比增长率
        percent_increases = []
        for r in rules:
            count8 = rule_counts[r]['count8']
            count10 = rule_counts[r]['count10']
            # 计算增长率百分比
            increase = ((count10 - count8) / count8) * 100
            percent_increases.append(increase)
        
        # 同时保存原始数值以便显示
        count8_values = [rule_counts[r]['count8'] for r in rules]
        count10_values = [rule_counts[r]['count10'] for r in rules]
        
        # 创建柱状图
        fig, ax = plt.subplots(figsize=(12, 6))
        
        # 设置柱状图位置
        x = np.arange(len(rules))
        width = 0.35
        
        # 绘制百分比增长柱状图
        bars = ax.bar(x, percent_increases, width, color='skyblue')
        
        # 添加一条0%参考线
        ax.axhline(y=0, color='gray', linestyle='-', alpha=0.3)
        
        # 添加标签和标题
        ax.set_xlabel('规则名称 (Rule Name)')
        ax.set_ylabel('增长率 (%)')
        ax.set_title('成功状态规则的 Count10 相对于 Count8 的增长率')
        ax.set_xticks(x)
        # 设置x轴标签旋转45度，避免文字重叠
        ax.set_xticklabels(rules, rotation=45, ha='right')
        plt.tight_layout()  # 调整布局
        
        # 在柱状图上方显示百分比数值
        def add_labels(rects):
            for i, rect in enumerate(rects):
                height = rect.get_height()
                # 根据增长正负选择不同的颜色
                color = 'red' if height < 0 else 'green'
                # 显示百分比和原始数值
                label_text = f"{height:.1f}%\n({count8_values[i]}→{count10_values[i]})"
                ax.annotate(label_text,
                            xy=(rect.get_x() + rect.get_width() / 2, height),
                            xytext=(0, 5),  # 5点垂直偏移
                            textcoords="offset points",
                            ha='center', va='bottom',
                            color=color, fontsize=8)
        
        add_labels(bars)
        
        # 根据数据动态调整y轴范围
        max_abs = max(abs(val) for val in percent_increases)
        y_max = max_abs * 1.2  # 留出一些边距
        ax.set_ylim(-y_max, y_max)
        
        # 保存图表
        output_image = csv_file_path.replace('.csv', '_rule_comparison_chart.png')
        plt.savefig(output_image, dpi=300)
        print(f"图表已保存到: {output_image}")
        
        # 显示图表
        plt.show()
        
    except Exception as e:
        print(f"处理过程中发生错误: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    csv_file = "统计不要删.csv"
    generate_comparison_chart(csv_file)